/*Taisija Ilja Sipols
 * VIDE: Visual Studio 2022
 * Iedvesmojumu nemu no ta darba kuru iesutiju agrak (ta bija veidota ar maksligu intelektu palidzibu)
 * ir pievienota zip faila
*/

using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace loalasls
{
    // klase, kas attēlo vienu failu sistēmas objektu (failu vai mapi)
    class FileSystemObject
    {
        public string Name; // objekta nosaukums
        public string Type; // objekta tips 
        public FileSystemObject[] children = new FileSystemObject[100]; // maksimalais objektu skaits,
                                                                        // ja bus vairak par 100 bus kluda par massiva indeksa parsniegsanu
        public FileSystemObject Parent; // atsauce uz vecāku mapi
        public int ChildCount = 0; // skaita cik bernu ir kopuma, visas mapes

        public FileSystemObject(string name, string type)
        {
            Name = name;
            Type = type;
        }

        // izvada bērnus - vai nu kā mapi, vai kā failu
        public void ShowChildren()
        {
            for (int i = 0; i < ChildCount; i++)
            {
                var child = children[i];
                if (child.Type == "folder")
                {
                    Console.WriteLine("/" + child.Name);
                }
                else
                {
                    Console.WriteLine("~[" + child.Name + "]~");
                }
            }
        }

        // pievieno bērna objektu
        public void AddChild(FileSystemObject child)
        {
            for (int i = 0; i < ChildCount; i++)
            {
                if (children[i].Name.ToLower() == child.Name.ToLower())
                {
                    Console.WriteLine("Object already exists");
                    return;
                }
            }
            children[ChildCount++] = child; //
            child.Parent = this;
        }

        // noņem bērnu pēc nosaukuma (ja ir), pārkārtojot masīvu
        public bool RemoveChild(string name)
        {
            for (int i = 0; i < ChildCount; i++)
            {
                if (children[i].Name.ToLower() == name.ToLower())
                {
                    if (children[i].Type.ToLower() == "folder" && children[i].ChildCount > 0)
                    {
                        Console.WriteLine("Folder is already empty, u sure u want to delete it Y/N?");
                        if (Console.ReadLine().ToLower() != "Y")
                        {
                            return false;
                        }
                    }
                    for (int j = i; j < ChildCount - 1; j++)
                    {
                        children[j] = children[j + 1];
                    }
                    ChildCount--;
                    return true;
                }
            }
            Console.WriteLine("Object not found.");
            return false;
        }

        // meklē bērnu pēc nosaukuma un atgriež objektu, ja atrod
        public FileSystemObject GetChild(string name) // redaktors
        {
            for (int i = 0; i < ChildCount; i++)
            {
                if (children[i].Name.ToLower() == name.ToLower())
                {
                    return children[i];
                }
            }
            return null;
        }
    }

    // klase, kas pārvalda visu failu sistēmu (komandrindas simulators)
    class FileSystem
    {
        private FileSystemObject root; // Galvenā saknes mape (C:)
        private FileSystemObject current; // Pašreizējā aktīvā mape

        public FileSystem()
        {
            root = new FileSystemObject("C:", "folder");
            current = root;
        }

        // atgriež pilnu ceļu uz aktīvo mapi
        private string GetPath()
        {
            string path = "";
            FileSystemObject node = current;
            while (node != null)
            {
                path = "/" + node.Name + path;
                node = node.Parent;
            }
            return path;
        }

        // galvenā metode, kas palaiž konsoli un apstrādā komandas
        public void Run()
        {
            while (true)
            {
                try
                {
                    Console.Write($"{GetPath()}>");
                    string input = Console.ReadLine();
                    if (string.IsNullOrEmpty(input)) // parnauda ja inputs nebija tukš
                    {
                        continue; // vienkarši turpina kodu
                    }
                    string[] parts = input.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // dzess visus space lai nebutu nekadas kludas
                    string cmd = parts[0].ToLower();
                    switch (cmd)
                    {
                        case "mkdir": // piesaista obejktam jaunu faili
                            for (int i = 1; i < parts.Length && i <= 3; i++)
                            {
                                current.AddChild(new FileSystemObject(parts[i], "folder")); // vieta " " nozime kada tipa fails bus piesaistits 
                            }
                            break;
                        case "create": // piesaista objektam jaunu datni 
                            for (int i = 1; i < parts.Length && i <= 3; i++)
                            {
                                current.AddChild(new FileSystemObject(parts[i], "file")); // vieta " " nozime kada tipa fails bus piesaistits 
                            }
                            break;
                        case "dir":
                            if (parts.Length == 1)
                            {
                                current.ShowChildren(); // izvada aktuālās mapes saturu
                            }
                            else if (parts.Length == 2 && parts[1].StartsWith(">"))
                            {
                                string FileName = parts[1].Substring(1); // noņem simbolu >
                                string content = "";
                                for (int i = 0; i < current.ChildCount; i++)
                                {
                                    var c = current.children[i];
                                    content += c.Type.ToLower() == "folder" ? "/" + c.Name + "\n" : "[" + c.Name + "] \n"; // tas ir saisinats cikls kas parbauda un izvada mapes elemnentus vai pasu mapi
                                }
                                File.WriteAllText(FileName + ".txt", content); // saglabā saturu failā
                                current.RemoveChild(FileName); // 
                                var newFile = new FileSystemObject(FileName, "File");
                                Console.WriteLine("File was saved in " + FileName);
                            }
                            break;
                        case "rm":
                            for (int i = 1; i < parts.Length && i <= 3; i++)
                            {
                                current.RemoveChild(parts[i]); // izdzēš norādīto mapi no sistēmas
                            }
                            break;
                        case "cd":
                            if (parts.Length > 2)
                            {
                                Console.WriteLine("Usage: cd <name>, cd .. or cd /");
                                break;
                            }
                            string target = parts[1];
                            if (target == "..")
                            {
                                if (current.Parent != null)
                                {
                                    current = current.Parent; // atgriežas uz augšu
                                }
                            }
                            else if (target == "/")
                            {
                                current = root; // atgriežas uz sākuma direktoriju
                            }
                            else
                            {
                                var dir = current.GetChild(target);
                                if (dir != null && dir.Type.ToLower() == "folder")
                                {
                                    current = dir; // iet mapē iekšā
                                }
                                else
                                {
                                    Console.WriteLine("Error: folder doesnt exist");
                                }
                            }
                            break;

                        case "edit":
                            if (parts.Length >= 2)
                            {
                                string name = parts[1];
                                var file = current.GetChild(name);
                                if (file != null && file.Type.ToLower() == "file")
                                {
                                    Console.WriteLine("Opening file: " + name);
                                    string filePath = name + ".txt";

                                    if (File.Exists(filePath))
                                    {
                                        Console.WriteLine(File.ReadAllText(filePath)); // 
                                    }
                                    else
                                    {
                                        Console.WriteLine("File is empty");
                                    }
                                }
                                else
                                {
                                    Console.WriteLine("File not found");
                                }
                            }
                            break;

                        case "clear":
                            Console.Clear(); 
                            break;
                        case "del":
                            for (int i = 1; i < parts.Length && i <= 3; i++)
                            {
                                string filepath = parts[i] + ".txt";
                                File.Delete(filepath); 
                                current.RemoveChild(parts[i]); // dzes no virtuālās failu sistēmas
                                Console.WriteLine("Deleted sucessfuly: " + parts[i]);
                            }
                            break;
                        case "exit":
                            return;
                        case "by":
                            return;
                        case "help":
                            Console.WriteLine("Available commands:");
                            Console.WriteLine("mkdir <name>     - Create folder");
                            Console.WriteLine("create <name>    - Create file");
                            Console.WriteLine("rm <name>        - Delete file/folder");
                            Console.WriteLine("dir              - List contents");
                            Console.WriteLine("cd <name|..>     - Change directory");
                            Console.WriteLine("edit <filename>  - Simulate editing file");
                            Console.WriteLine("clear <console>  - Clear console");
                            Console.WriteLine("exit/by          - Exit the program");
                            Console.WriteLine("del              - Delete file");
                            break;
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error:" + e.Message); // Izvada kļūdas paziņojumu
                }
            }
        }
    }

    // inicializē failu sistēmu
    class Program
    {
        static void Main(string[] args)
        {
            FileSystem fs = new FileSystem();
            fs.Run();
        }
    }
}
